/******************************************
 * Author: Dave Spadea
 * Date: June 2011
 * 
 * This code is released by David Spadea for general consumption 
 * under the Apache Software License.
 * 
 */

package net.spadea.sample;

import net.spadea.framework.messaging.Message;
import net.spadea.framework.service.FrameworkService;

import net.spadea.sample.requests.*;

public class MyService extends FrameworkService {

	/* Services must provide their own main() method. This lets you do any argument processing
	 * your service may require before actually kicking off the worker threads.
	 */
	public static void main(String[] args) {
		
		/* Do any pre-startup processing of command line args here. */
		
		/* Ok, instantiate the service, and start the specified number of workers (could be from a command line argument),
		 * Note that start_workers does return, so you can theoretically start several worker classes, effectively making
		 * one uber-service out of several implementations. You may want to implement a single logical service as a set of
		 * smaller services in the same runtime that pass control to each other through the controller. That allows you to
		 * resubmit processing at a given step in the service rather than starting all over. It also allows you to run each
		 * step in separate sets of threads, which may improve performance.
		 */
		
		MyService ms = new MyService();
		ms.start_workers(10);
		log.info("Workers started.");
	}
	
	
	@Override
	public void processMessage(Message msg) throws Exception {
		
		
		/* The Message coming in is a generic message type. It has get() and set() methods, 
		 * but will not contain any business logic that might be in the specific subclasses.
		 * Right now, the only way to convert it is to serialize the message back to YAML using 
		 * msg.toString(), and then load() it back into a specific message class. I know this is 
		 * awful, and I'm looking into a better way to do it.
		 */
		
		SampleWorkflowEvent swe = new SampleWorkflowEvent();
		swe.load(msg.toString());
		
		log.info("Got message! Setting to MESSAGE_ENRICHED and sending back...");
		
		/* Implement message processing here */
		

		
		/* Enrich the event with data that was generated in the current service, making it 
		 * available for downstream processes. 
		 */
		
		//swe.set("some_new_key", value_from_processing);
		
		/* Set the final status and send it back. */
		swe.setStatus("MESSAGE_ENRICHED");
		
		/* and finally send the message back to the controller. */
		swe.send();
		
		/* NOTE: There's no rule saying that a given service can only send one status back. If your processing
		 * consists of several logical steps, you can setStatus() and send() after each one. That has several 
		 * nice effects:
		 * 
		 * First, it establishes a processing timeline in the controller logs and gives you checkpoints for
		 * troubleshooting. If processing doesn't complete for some reason, a quick look at the controller logs
		 * will give you a good indication of how far processing got before it died.
		 * 
		 * Second, you can hook external processes off of these intermediate events. That way your service doesn't need
		 * to completely finish if it's at least passed a point where it's useful to some external process. 
		 */
		
	}

}
